
#include "sec_common.h"
#include "e_os.h"
#include "hard.h"
//#include <openssl/modes.h>
//#include <openssl/sms4.h>
unsigned char sm4_key[] = {
		/* KEY 1 for ecb */
		0x77,0x7f,0x23,0xc6,0xfe,0x7b,0x48,0x73,0xdd,0x59,0x5c,0xff,0xf6,0x5f,0x58,0xec,
		/* KEY 2 for ecb */
		0x77,0x7f,0x23,0xc6,0xfe,0x7b,0x48,0x73,0xdd,0x59,0x5c,0xff,0xf6,0x5f,0x58,0xec,
		/* KEY 3 for cbc */
		0x77,0x7f,0x23,0xc6,0xfe,0x7b,0x48,0x73,0xdd,0x59,0x5c,0xff,0xf6,0x5f,0x58,0xec,
		/* KEY 4 for cbc */
		0x77,0x7f,0x23,0xc6,0xfe,0x7b,0x48,0x73,0xdd,0x59,0x5c,0xff,0xf6,0x5f,0x58,0xec};

unsigned char sm4_iv[] = {
		/* IV 1 for key 3 */
		0x77,0x7f,0x23,0xc6,0xfe,0x7b,0x48,0x73,0xdd,0x59,0x5c,0xff,0xf6,0x5f,0x58,0xec,
		/* IV 2 for key 4 */
		0xd5,0x35,0x56,0x7a,0x44,0x33,0x2e,0xa7,0x59,0x97,0xc5,0x84,0x32,0xed,0x22,0x5c};

unsigned char sm4_data[] = {
		/* DATA 1 for ecb */
		0x5f,0xe9,0x7c,0xcd,0x58,0xfe,0xd7,0xab,0x41,0xf7,0x1e,0xfb,0xfd,0xe7,0xe1,0x46,
		/* DATA 2 for ecb */
		0x5b,0xfc,0x62,0xc2,0x4d,0xf5,0x27,0xf8,0x3f,0x1f,0xe9,0xe8,0xef,0xef,0x43,0x8d,
		/* DATA 3 for cbc */
		0x5f,0xe9,0x7c,0xcd,0x58,0xfe,0xd7,0xab,0x41,0xf7,0x1e,0xfb,0xfd,0xe7,0xe1,0x46,
		0x5b,0xfc,0x62,0xc2,0x4d,0xf5,0x27,0xf8,0x3f,0x1f,0xe9,0xe8,0xef,0xef,0x43,0x8d,
		/* DATA 4 for cbc */
		0x3f,0x76,0x25,0x5a,0xfd,0xef,0x72,0x63,0xdb,0xff,0xd7,0x9f,0xef,0xe9,0x07,0x9a,
		0xff,0xe6,0x5d,0x32,0x53,0x1f,0xd7,0xb7,0xfe,0xb3,0xe4,0x58,0x72,0xbb,0xd9,0x5a};



unsigned char sm4_stddata[] = {
		/* STD OUT 1 for ecb */
		0x56,0xda,0x23,0xe2,0x5f,0xa7,0xcd,0x82,0x5d,0x51,0xc2,0x20,0xf5,0x98,0x09,0x0b,
		/* STD OUT 2 for ecb */
		0xc6,0x0d,0xfa,0x4e,0x6e,0x77,0x3c,0xc1,0x2b,0x2a,0x1c,0xd7,0xf2,0xd6,0x59,0x78,
		/* STD OUT 3 for cbc */
		0xdc,0x8e,0xf8,0x0e,0x1d,0x03,0xaf,0x92,0x8d,0x72,0x58,0x8e,0x99,0x1e,0xe3,0xfa,
		0xd5,0x35,0x56,0x7a,0x44,0x33,0x2e,0xa7,0x59,0x97,0xc5,0x84,0x32,0xed,0x22,0x5c,
		/* STD OUT 4 for cbc */
		0xf2,0x02,0xf0,0x0a,0x4a,0xa9,0xc6,0x08,0x80,0x53,0xe1,0xdf,0x42,0x44,0x9b,0xf9,
		0x44,0x91,0x55,0x31,0x68,0x0e,0x2a,0xf4,0x4c,0x66,0x02,0x33,0x9f,0x2a,0xe4,0x52};

sm4_ecb_ssl_hard_test(int fd)
{
	volatile unsigned char *mem;
	struct cipher_api capi;
	unsigned int max_len = max_crypto_len;
	unsigned char *out,*dt;
	unsigned int i;

	capi.alg = SM4;
	capi.type  = ECB;
	capi.as = INITFINAL;
	capi.key_len = 16;
	capi.iv_len = 16;
	capi.data_len = (( 0x10|(unsigned)(rand()) )&(max_crypto_len/2-1))&0xfffffff0 ;

	debug("max_crypto_len is 0x%x,data_len is 0x%x,key_size is 0x%x\n",max_len,capi.data_len,capi.key_len);

	mem = malloc(CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len);
	out = malloc(capi.data_len);
	dt = malloc(capi.data_len);


	set_rand_mem((void *)(mem+CHEAD_SIZE),capi.key_len);
	set_rand_mem((void *)(mem+CHEAD_SIZE+capi.key_len),capi.iv_len);
	set_rand_mem((void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len);

	memcpy((void *)dt,(void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len);

/////////////////////////////////////////////////////////////////////////////
//enc
/////////////////////////////////////////////////////////////////////////////

	capi.opt = ENC;

	memcpy((void *)mem,(void *)(&capi),CHEAD_SIZE);

#ifdef DATA_VIEW
	debug("before ecb(sm4) enc:\n");
	for(i=48;i<20+48;i++)
	{
		debug("%x ",mem[i]);
	}
	debug("\n");
#endif

	ioctl(fd,_IOC(0x00,CCP903T_PCIE_MAGIC, ACLASS_CIPHER,CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len),mem);
	while(!(mem[3]&DDONE_MASK));

#ifdef DATA_VIEW
	debug("\nafter ecb(sm4) enc:\n");
	for(i=48;i<20+48;i++)
	{
		debug("%x ",mem[i]);
	}
	debug("\n");
#endif

/////////////////////////////////////////////////////////////////////////////
//dec
/////////////////////////////////////////////////////////////////////////////

	capi.opt = DEC;

	memcpy((void *)mem,(void *)(&capi),CHEAD_SIZE);

	ioctl(fd,_IOC(0x00,CCP903T_PCIE_MAGIC, ACLASS_CIPHER,CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len),mem);
	while(!(mem[3]&DDONE_MASK));

	if(!memcmp((void *)dt,(void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len))
		debug("sm4_ecb_ssl_hard dec test ok!\n");
	else
	{
		errout("sm4_ecb_ssl_hard  dec test error!\n");
		fail_prosess();
	}

	free((void *)out);
	free((void *)mem);
	free((void *)dt);
}
sm4_ctr_ssl_hard_test(int fd)
{
	volatile unsigned char *mem;
	struct cipher_api capi;
	unsigned int max_len = max_crypto_len;
	unsigned char *out,*dt,iv_tmp[32];
	unsigned int i;

	capi.alg = SM4;
	capi.type  = CTR;
	capi.as = INITFINAL;
	capi.key_len = 16;
	capi.iv_len = 16*2;
	capi.data_len = (( 0x10|(unsigned)(rand()) )&(max_crypto_len/2-1))&0xfffffff0 ;

	debug("max_crypto_len is 0x%x,data_len is 0x%x,key_size is 0x%x\n",max_len,capi.data_len,capi.key_len);

	mem = malloc(CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len);
	out = malloc(capi.data_len);
	dt = malloc(capi.data_len);


	set_rand_mem((void *)(mem+CHEAD_SIZE),capi.key_len);
	set_rand_mem((void *)(mem+CHEAD_SIZE+capi.key_len),capi.iv_len);
	set_rand_mem((void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len);

	memcpy((void *)iv_tmp,(void *)(mem+CHEAD_SIZE+capi.key_len),capi.iv_len);
	memcpy((void *)dt,(void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len);

/////////////////////////////////////////////////////////////////////////////
//enc
/////////////////////////////////////////////////////////////////////////////

	capi.opt = ENC;

	memcpy((void *)mem,(void *)(&capi),CHEAD_SIZE);

#ifdef DATA_VIEW
	debug("before ctr(sm4) enc:\n");
	for(i=48;i<20+48;i++)
	{
		debug("%x ",mem[i]);
	}
	debug("\n");
#endif

	ioctl(fd,_IOC(0x00,CCP903T_PCIE_MAGIC, ACLASS_CIPHER,CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len),mem);
	while(!(mem[3]&DDONE_MASK));

#ifdef DATA_VIEW
	debug("\nafter ctr(sm4) enc:\n");
	for(i=48;i<20+48;i++)
	{
		debug("%x ",mem[i]);
	}
	debug("\n");
#endif

/////////////////////////////////////////////////////////////////////////////
//dec
/////////////////////////////////////////////////////////////////////////////

	capi.opt = DEC;

	memcpy((void *)mem,(void *)(&capi),CHEAD_SIZE);
	memcpy((void *)(mem+CHEAD_SIZE+capi.key_len),(void *)iv_tmp,capi.iv_len);

	ioctl(fd,_IOC(0x00,CCP903T_PCIE_MAGIC, ACLASS_CIPHER,CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len),mem);
	while(!(mem[3]&DDONE_MASK));

	if(!memcmp((void *)dt,(void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len))
		debug("sm4_ctr_ssl_hard dec test ok!\n");
	else
	{
		errout("sm4_ctr_ssl_hard  dec test error!\n");
		fail_prosess();
	}

	free((void *)out);
	free((void *)mem);
	free((void *)dt);
}
sm4_cbc_ssl_hard_test(int fd)
{
	volatile unsigned char *mem;
	struct cipher_api capi;
	unsigned int max_len = max_crypto_len;
	unsigned char *out,*dt,iv_tmp[16];
	unsigned int i;

	capi.alg = SM4;
	capi.type  = CBC;
	capi.as = INITFINAL;
	capi.key_len = 16;
	capi.iv_len = 16;
	capi.data_len = (( 0x10|(unsigned)(rand()) )&(max_crypto_len/2-1))&0xfffffff0 ;

	debug("max_crypto_len is 0x%x,data_len is 0x%x,key_size is 0x%x\n",max_len,capi.data_len,capi.key_len);

	mem = malloc(CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len);
	out = malloc(capi.data_len);
	dt = malloc(capi.data_len);


	set_rand_mem((void *)(mem+CHEAD_SIZE),capi.key_len);
	set_rand_mem((void *)(mem+CHEAD_SIZE+capi.key_len),capi.iv_len);
	set_rand_mem((void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len);

	memcpy((void *)iv_tmp,(void *)(mem+CHEAD_SIZE+capi.key_len),capi.iv_len);
	memcpy((void *)dt,(void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len);

/////////////////////////////////////////////////////////////////////////////
//enc
/////////////////////////////////////////////////////////////////////////////

	capi.opt = ENC;

	memcpy((void *)mem,(void *)(&capi),CHEAD_SIZE);

#ifdef DATA_VIEW
	debug("before cbc(sm4) enc:\n");
	for(i=48;i<20+48;i++)
	{
		debug("%x ",mem[i]);
	}
	debug("\n");
#endif

	ioctl(fd,_IOC(0x00,CCP903T_PCIE_MAGIC, ACLASS_CIPHER,CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len),mem);
	while(!(mem[3]&DDONE_MASK));

#ifdef DATA_VIEW
	debug("\nafter cbc(sm4) enc:\n");
	for(i=48;i<20+48;i++)
	{
		debug("%x ",mem[i]);
	}
	debug("\n");
#endif

/////////////////////////////////////////////////////////////////////////////
//dec
/////////////////////////////////////////////////////////////////////////////

	capi.opt = DEC;

	memcpy((void *)mem,(void *)(&capi),CHEAD_SIZE);
	memcpy((void *)(mem+CHEAD_SIZE+capi.key_len),(void *)iv_tmp,capi.iv_len);

	ioctl(fd,_IOC(0x00,CCP903T_PCIE_MAGIC, ACLASS_CIPHER,CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len),mem);
	while(!(mem[3]&DDONE_MASK));

	if(!memcmp((void *)dt,(void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len))
		debug("sm4_ecb_ssl_hard dec test ok!\n");
	else
	{
		errout("sm4_ecb_ssl_hard  dec test error!\n");
		fail_prosess();
	}

	free((void *)out);
	free((void *)mem);
	free((void *)dt);
}
sm4_ofb_ssl_hard_test(int fd)
{
	volatile unsigned char *mem;
	struct cipher_api capi;
	unsigned int max_len = max_crypto_len;
	unsigned char *out,*dt,iv_tmp[16];
	unsigned int i;

	capi.alg = SM4;
	capi.type  = OFB;
	capi.as = INITFINAL;
	capi.key_len = 16;
	capi.iv_len = 16;
	capi.data_len = (( 0x10|(unsigned)(rand()) )&(max_crypto_len/2-1))&0xfffffff0 ;

	debug("max_crypto_len is 0x%x,data_len is 0x%x,key_size is 0x%x\n",max_len,capi.data_len,capi.key_len);

	mem = malloc(CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len);
	out = malloc(capi.data_len);
	dt = malloc(capi.data_len);


	set_rand_mem((void *)(mem+CHEAD_SIZE),capi.key_len);
	set_rand_mem((void *)(mem+CHEAD_SIZE+capi.key_len),capi.iv_len);
	set_rand_mem((void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len);

	memcpy((void *)iv_tmp,(void *)(mem+CHEAD_SIZE+capi.key_len),capi.iv_len);
	memcpy((void *)dt,(void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len);

/////////////////////////////////////////////////////////////////////////////
//enc
/////////////////////////////////////////////////////////////////////////////

	capi.opt = ENC;

	memcpy((void *)mem,(void *)(&capi),CHEAD_SIZE);

#ifdef DATA_VIEW
	debug("before ofb(sm4) enc:\n");
	for(i=48;i<20+48;i++)
	{
		debug("%x ",mem[i]);
	}
	debug("\n");
#endif

	ioctl(fd,_IOC(0x00,CCP903T_PCIE_MAGIC, ACLASS_CIPHER,CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len),mem);
	while(!(mem[3]&DDONE_MASK));

#ifdef DATA_VIEW
	debug("\nafter ofb(sm4) enc:\n");
	for(i=48;i<20+48;i++)
	{
		debug("%x ",mem[i]);
	}
	debug("\n");
#endif

/////////////////////////////////////////////////////////////////////////////
//dec
/////////////////////////////////////////////////////////////////////////////

	capi.opt = DEC;

	memcpy((void *)mem,(void *)(&capi),CHEAD_SIZE);
	memcpy((void *)(mem+CHEAD_SIZE+capi.key_len),(void *)iv_tmp,capi.iv_len);

	ioctl(fd,_IOC(0x00,CCP903T_PCIE_MAGIC, ACLASS_CIPHER,CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len),mem);
	while(!(mem[3]&DDONE_MASK));

	if(!memcmp((void *)dt,(void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len))
		debug("sm4_ofb_ssl_hard dec test ok!\n");
	else
	{
		errout("sm4_ofb_ssl_hard  dec test error!\n");
		fail_prosess();
	}

	free((void *)out);
	free((void *)mem);
	free((void *)dt);
}
sm4_cfb_ssl_hard_test(int fd)
{
	volatile unsigned char *mem;
	struct cipher_api capi;
	unsigned int max_len = max_crypto_len;
	unsigned char *out,*dt,iv_tmp[16];
	unsigned int i;

	capi.alg = SM4;
	capi.type  = CFB;
	capi.as = INITFINAL;
	capi.key_len = 16;
	capi.iv_len = 16;
	capi.data_len = (( 0x10|(unsigned)(rand()) )&(max_crypto_len/2-1))&0xfffffff0 ;

	debug("max_crypto_len is 0x%x,data_len is 0x%x,key_size is 0x%x\n",max_len,capi.data_len,capi.key_len);

	mem = malloc(CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len);
	out = malloc(capi.data_len);
	dt = malloc(capi.data_len);


	set_rand_mem((void *)(mem+CHEAD_SIZE),capi.key_len);
	set_rand_mem((void *)(mem+CHEAD_SIZE+capi.key_len),capi.iv_len);
	set_rand_mem((void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len);

	memcpy((void *)iv_tmp,(void *)(mem+CHEAD_SIZE+capi.key_len),capi.iv_len);
	memcpy((void *)dt,(void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len);

/////////////////////////////////////////////////////////////////////////////
//enc
/////////////////////////////////////////////////////////////////////////////

	capi.opt = ENC;

	memcpy((void *)mem,(void *)(&capi),CHEAD_SIZE);

#ifdef DATA_VIEW
	debug("before cfb(sm4) enc:\n");
	for(i=48;i<20+48;i++)
	{
		debug("%x ",mem[i]);
	}
	debug("\n");
#endif

	ioctl(fd,_IOC(0x00,CCP903T_PCIE_MAGIC, ACLASS_CIPHER,CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len),mem);
	while(!(mem[3]&DDONE_MASK));

#ifdef DATA_VIEW
	debug("\nafter cfb(sm4) enc:\n");
	for(i=48;i<20+48;i++)
	{
		debug("%x ",mem[i]);
	}
	debug("\n");
#endif

/////////////////////////////////////////////////////////////////////////////
//dec
/////////////////////////////////////////////////////////////////////////////

	capi.opt = DEC;

	memcpy((void *)mem,(void *)(&capi),CHEAD_SIZE);
	memcpy((void *)(mem+CHEAD_SIZE+capi.key_len),(void *)iv_tmp,capi.iv_len);

	ioctl(fd,_IOC(0x00,CCP903T_PCIE_MAGIC, ACLASS_CIPHER,CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len),mem);
	while(!(mem[3]&DDONE_MASK));

	if(!memcmp((void *)dt,(void *)(mem+CHEAD_SIZE+capi.key_len+capi.iv_len),capi.data_len))
		debug("sm4_cfb_ssl_hard dec test ok!\n");
	else
	{
		errout("sm4_cfb_ssl_hard  dec test error!\n");
		fail_prosess();
	}

	free((void *)out);
	free((void *)mem);
	free((void *)dt);
}
sm4_cbc_ssl_hard_key32_speed(int fd)
{
	int tcnt=100,MNUM=1000;
	volatile unsigned char *mem;
	struct cipher_api capi;
	unsigned int max_len = max_crypto_len; //16k
	unsigned char *out,*dt,iv_tmp[16];
	unsigned int i;
	struct timeval tv1,tv2;

	int cpid;
	int semval;
	int time,speed;

	capi.alg = SM4;
	capi.type  = CBC;
	capi.as = INITFINAL;
	capi.key_len = 16;
	capi.iv_len = 16;
	capi.data_len = (max_crypto_len-100)&0xfffffff0;

	debug("max_crypto_len is 0x%x,data_len is 0x%x,key_size is 0x%x\n",max_len,capi.data_len,capi.key_len);

	for(i=0;i<tcnt-1;i++)
	{
		cpid = fork();
		if(cpid==0)
			break;
	}
//	printf("i = %d\n",i);
	mem= malloc(CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len);

/////////////////////////////////////////////////////////////////////////////
//enc
/////////////////////////////////////////////////////////////////////////////

	capi.opt = ENC;

	memcpy((void *)mem,(void *)(&capi),CHEAD_SIZE);

	if(cpid==0)
	{
		do{
			sem_getvalue(usem->sem,&semval);
		}
		while(semval==1);
	}else{
		sem_wait(usem->sem);
		gettimeofday(&tv1, NULL);
	}

	for(i=0;i<MNUM;i++)
	{

		ioctl(fd,_IOC(0x00,CCP903T_PCIE_MAGIC, ACLASS_CIPHER,CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len),mem);

		while(!(mem[3]&DDONE_MASK));
	}

	sem_wait(dsem->sem);

	if(cpid==0)
	{
		free((void *)mem);
		exit(0);
	}else{
		do{
			sem_getvalue(dsem->sem,&semval);
		}
		while(semval!=(MAX_SEM_CNT-tcnt));
		gettimeofday(&tv2, NULL);
		free((void *)mem);
	}
	sem_post(usem->sem);

	for(i=0;i<tcnt;i++)
	{
		sem_post(dsem->sem);
	}

	time = (tv2.tv_sec-tv1.tv_sec)*1000000+tv2.tv_usec-tv1.tv_usec;

	speed = MNUM*tcnt*capi.data_len/time;
	speed*=8;

	spd_dbg("%s,CBC encrypt data_len %d,tcnt %d,speed is %dMbps,time %d us\n",__FILE__,capi.data_len,tcnt,speed,time);

/////////////////////////////////////////////////////////////////////////////
//dec
/////////////////////////////////////////////////////////////////////////////
	for(i=0;i<tcnt-1;i++)
	{
		cpid = fork();
		if(cpid==0)
			break;
	}

	mem= malloc(CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len);

	capi.opt = DEC;

	memcpy((void *)mem,(void *)(&capi),CHEAD_SIZE);

	if(cpid==0)
	{
		do{
			sem_getvalue(usem->sem,&semval);
		}
		while(semval==1);
	}else{
		sem_wait(usem->sem);
		gettimeofday(&tv1, NULL);
	}

	for(i=0;i<MNUM;i++)
	{
		ioctl(fd,_IOC(0x00,CCP903T_PCIE_MAGIC, ACLASS_CIPHER,CHEAD_SIZE+capi.key_len+capi.iv_len+capi.data_len),mem);

		while(!(mem[3]&DDONE_MASK));
	}
	sem_wait(dsem->sem);

	if(cpid==0)
	{
		free((void *)mem);
		exit(0);
	}else{
		do{
			sem_getvalue(dsem->sem,&semval);
		}
		while(semval!=(MAX_SEM_CNT-tcnt));
		gettimeofday(&tv2, NULL);
		free((void *)mem);
	}

	sem_post(usem->sem);
	for(i=0;i<tcnt;i++)
	{
		sem_post(dsem->sem);
	}

	time = (tv2.tv_sec-tv1.tv_sec)*1000000+tv2.tv_usec-tv1.tv_usec;

	speed = MNUM*tcnt*capi.data_len/time;
	speed*=8;

	spd_dbg("%s,CBC decrypt data_len %d,tcnt %d,speed is %dMbps,time %d us\n",__FILE__,capi.data_len,tcnt,speed,time);

}
